package com.mgfireworks.mgplatform.mgshop.main;

import cn.hn.java.summer.db.BaseDao;
import cn.hn.java.summer.db.multiple.DataSource1;
import cn.hn.java.summer.exception.BusinessException;
import cn.hn.java.summer.utils.JsonUtils;
import cn.hn.java.summer.utils.codec.CodecUtils;
import com.mgfireworks.mgplatform.mgshop.model.OrganizationVo;
import com.mgfireworks.mgplatform.mgshop.model.ShopUserInfoVo;
import com.mgfireworks.mgplatform.mgshop.model.ShopUserVo;
import com.mgfireworks.mgplatform.mgshop.model.map.MapPoint;
import com.mgfireworks.mgplatform.mgshop.model.weixin.*;
import com.mzlion.easyokhttp.HttpClient;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

/**
 * Created by xw2sy on 2017-04-29.
 */
@Service
public class AccountService extends BaseDao<DataSource1>{

    @Autowired
    private WeiXinAppConfig weiXinAppConfig;

    @Autowired
    private AreaService areaService;

    /**
     * 微信接入验证接口
     * @param info 微信接入验证信息
     * @return echostr
     */
    public String weiXinAccessValid(WeiXinValidInfo info){
        String[] arr=new String[]{weiXinAppConfig.getToken(),info.getTimestamp(),info.getNonce()};
        Arrays.sort(arr);
        String signature = CodecUtils.sha1Hex(String.join("",arr));
        if(info.getSignature().equals(signature)){
            return info.getEchostr();
        }
        return "";
    }

    /**
     * 取微信token
     */
    public void getWeiXinAccessToken(){
        String responseData = HttpClient
                // 请求方式和请求url
                .get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential")
                //设置请求参数
                .queryString("appid",weiXinAppConfig.getAppId())
                .queryString("secret",weiXinAppConfig.getAppsecret())
                .asString();
        WeXinAccessToken token=JsonUtils.parse(responseData,WeXinAccessToken.class);
        weiXinAppConfig.setWeXinAccessToken(token);
    }

    /**
     * 取微信用户id
     * @param login 登录返回信息
     * @return 微信用户id信息
     */
    public WeiXinOpenidInfo getWeiXinUserOpenid(WeiXinLogin login) throws BusinessException {
        String result= HttpClient.get("https://api.weixin.qq.com/sns/oauth2/access_token")
                .queryString("appid",weiXinAppConfig.getAppId())
                .queryString("secret",weiXinAppConfig.getAppsecret())
                .queryString("code",login.getCode())
                .queryString("grant_type","authorization_code")
                .asString();
        WeiXinOpenidInfo openidInfo= JsonUtils.parse(result,WeiXinOpenidInfo.class);
        if(openidInfo.getErrcode()!=null){
            throw new BusinessException("登录失败："+openidInfo.getErrcode());
        }
        return openidInfo;
    }

    /**
     * 拉取微信用户信息
     * @param openidInfo 用户id信息
     * @return 用户信息
     */
    public ShopUserVo getWeiXinUserInfo(WeiXinOpenidInfo openidInfo) throws BusinessException {
        String result= HttpClient.get("https://api.weixin.qq.com/sns/userinfo")
                .queryString("appid",weiXinAppConfig.getAppId())
                .queryString("openid",openidInfo.getOpenid())
                .queryString("access_token",openidInfo.getAccess_token())
                .queryString("lang","zh_CN")
                .asString();
        WeiXinUserInfo userInfo= JsonUtils.parse(result,WeiXinUserInfo.class);
        if(userInfo.getErrcode()!=null){
            throw new BusinessException("获取用户信息失败："+userInfo.getErrcode());
        }

        ShopUserVo shopUserVo=new ShopUserVo();
        shopUserVo.setOpenid(userInfo.getOpenid());
        shopUserVo.setUserAccount(userInfo.getOpenid());
        shopUserVo.setNickname(userInfo.getNickname());
        shopUserVo.setSex(userInfo.getSex());
        shopUserVo.setHeadimgurl(userInfo.getHeadimgurl());
        return shopUserVo;
    }

    /**
     * 保存微信登录成功后记录登录信息
     * @param shopUser 微信用户信息
     */
    public void saveWeiXinUserLogin(ShopUserVo shopUser){
        ShopUserVo su= get(ShopUserVo.class,ce().set("openid",shopUser.getOpenid()));
        if(su==null){
            shopUser.setCreateTime(DateTime.now().toDate());
            this.insert(shopUser);
        }else{
            shopUser.setUserId(su.getUserId());
            shopUser.setLoginTime(DateTime.now().toDate());
            this.update(shopUser);
        }
    }

    /**
     * 登录到微信
     * @param info 微信登录信息
     */
    public ShopUserVo loginToWeiXin(WeiXinLogin info) throws BusinessException {
        //1.先查询相同code是否已登录
        ShopUserVo loginCode= get(ShopUserVo.class,ce().set("loginCode",info.getCode()));
        if(loginCode!=null){
            return loginCode;
        }
        //2.登录微信取用户id
        WeiXinOpenidInfo openidInfo= getWeiXinUserOpenid(info);
        //3.拉取微信用户信息
        ShopUserVo shopUser= getWeiXinUserInfo(openidInfo);
        shopUser.setLoginCode(info.getCode());
        //4.保存用户信息
        saveWeiXinUserLogin(shopUser);
        return shopUser;
    }

    /**
     * 清除用户账户缓存
     * @param userAccount
     */
    @CacheEvict(value = "userInfo", key = "'getShopUser'+#userAccount")
    public void removeShopUserCache(String userAccount){
    }

    /**
     * 取店铺用户
     * @param userAccount 用户账号
     * @return 店铺用户信息
     */
    @Cacheable(value = "userInfo", key = "'getShopUser'+#userAccount")
    public ShopUserVo getShopUser(String userAccount){
        return get(ShopUserVo.class,ce().set("userAccount",userAccount));
    }

    /**
     * 清除用户信息缓存
     * @param userId
     */
    @Cacheable(value = "userInfo", key = "'getShopUserInfo'+#userId")
    public void removeShopUserInfoCache(int userId){
    }

    /**
     * 取店铺用户信息
     * @param userId 用户id
     * @return
     */
    @Cacheable(value = "userInfo", key = "'getShopUserInfo'+#userId")
    public ShopUserInfoVo getShopUserInfo(int userId){
        return get(ShopUserInfoVo.class,ce().set("userId",userId));
    }

    /**
     * 更新店铺用户信息缓存
     * @param userId
     * @param userInfoVo
     * @return
     */
    @CachePut(value = "userInfo", key = "'getShopUserInfo'+#userId")
    public ShopUserInfoVo updateShopUserInfoCache(int userId, ShopUserInfoVo userInfoVo){
        //使用用户地址省市区全名获取所在区域所有的二级代理商
        List<OrganizationVo> orgs= areaService.getOrgsByAreaFullName(userInfoVo.getAreaFullName());
        for(OrganizationVo org : orgs){
            if(org.getRangeMarks()==null){
                continue;
            }
            MapPoint[] points= JsonUtils.parse(org.getRangeMarks(), MapPoint[].class);
            //逐个检查每个二级代理商，找到用户坐标在在代理商区域范围内的代理商
            boolean isInArea=areaService.checkMapPointIsPolygon(userInfoVo.getPoint(),points);
            if(isInArea){
                userInfoVo.setShopOrgId(org.getOrgId());
                break;
            }
        }
        return userInfoVo;
    }
}
